package com.xinxing.learning.batch.service.batch;

import com.xinxing.learning.batch.common.LogConstants;
import com.xinxing.learning.batch.common.SyncConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.*;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class JobLauncherService {
    @Autowired
    private JobLauncher jobLauncher;

    public Map<String, Object> startJob(Job job, JobParameters jobParameters) throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
        Map<String, Object> resultMap = new HashMap<>();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start(job.getName());
        JobExecution jobExecution = jobLauncher.run(job, jobParameters);
        StringBuffer stringBuffer = new StringBuffer();
        Collection<StepExecution> stepExecutions = jobExecution.getStepExecutions();
        stepExecutions.forEach(stepExecution -> {
            stringBuffer.append("readCount:" + stepExecution.getCommitCount() + LogConstants.LOG_STR_COMMA);
            stringBuffer.append("filterCount:" + stepExecution.getFilterCount() + LogConstants.LOG_STR_COMMA);
            stringBuffer.append("commitCount:" + stepExecution.getCommitCount() + LogConstants.LOG_STR_COMMA);
            stringBuffer.append("writeCount:" + stepExecution.getWriteCount());
        });
        stopWatch.stop();
        ExitStatus exitStatus = jobExecution.getExitStatus();
        String returnStr = System.lineSeparator() + "resultCount: " + stringBuffer.toString()
                + System.lineSeparator() + "exitStatus: " + exitStatus
                + System.lineSeparator() + "timeInfo: " + stopWatch.prettyPrint();
        log.info(returnStr);
        resultMap.put(SyncConstants.STR_RETURN_RESULT, returnStr);
        resultMap.put(SyncConstants.STR_RETURN_EXITSTATUS, exitStatus);
        return resultMap;
    }
}
